﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Traders.Controllers;
using Traders.Views;

namespace Traders.Models
{
    public class AccountManager : TradersEvent
    {
        #region Implementacja eventów z interfejsu TradersEvent

        public event EventHandler<TradersEventArgs> EventHandler;

        public void FireEvent(TradersEventArgs e)
        {
            if (EventHandler != null)
                EventHandler(this, e);
        }

        public void HandleEvent(object sender, TradersEventArgs e)
        {

        }

        #endregion

        private List<Account> _accounts = new List<Account>();
        private bool _initialized = false;

        public List<Account> Accounts
        {
            get { return _accounts; }
        }

        public AccountManager()
        {
            _accounts = FileManager.FileManager.Deserialize<List<Account>>("accounts.xml");
            _initialized = true;
        }

        public void ConnectAccounts(ConnectingProgress p)
        {
            while (!_initialized) ;
            int max = _accounts.Count;
            int progress = 0;
            foreach (Account a in _accounts)
            {
                progress += (int)(Math.Ceiling(100 / (double)max));
                p.UpdateProgress(progress);
                if (!a.Connect())
                {
                    // Jeśli połączenie się nie uda, odpalamy event ConnectionError, a potem wychodzimy z funkcji
                    TradersEventArgs e = new TradersEventArgs();
                    e.Action = "ConnectionError";
                    e.Tag = a;
                    FireEvent(e);
                    return;
                }
                else
                {
                    TradersEventArgs e = new TradersEventArgs();
                    e.Action = "AccountConnected";
                    e.Tag = a;
                    FireEvent(e);
                }
            }

            TradersEventArgs args = new TradersEventArgs();
            args.Action = "ConnectionSuccess";
            FireEvent(args);

        }

        public void ConnectAccount(Account account)
        {
            var accounts =
                from a in _accounts
                where a.Broker == account.Broker && a.Login == account.Login
                select a;

            if (accounts.Count() > 0) return;

            if (account.Connect())
            {
                TradersEventArgs e = new TradersEventArgs();
                e.Action = "AccountConnected";
                e.Tag = account;
                FireEvent(e);
                _accounts.Add(account);
                FileManager.FileManager.Serialize<List<Account>>("accounts.xml", _accounts);
            }
            else
            {
                TradersEventArgs e = new TradersEventArgs();
                e.Action = "NewConnectionError";
                e.Tag = account;
                FireEvent(e);
            }

        }
        
        internal Account GetAccount(string Broker, string Login)
        {
            // Korzystamy z predykatu - to co ponizej jest rownowazne
            // Predicate<Account> pred = (a) => (a.Broker == Broker && a.Login == Login);
            // if (pred(new Account(Login, "asd", Broker))) Console.WriteLine("asd");
            return _accounts.Find((a) => (a.Broker == Broker && a.Login == Login));
        }
    }
}
